package com.andnnl.ratelimit;

import cn.hutool.core.thread.ThreadUtil;
import com.google.common.util.concurrent.RateLimiter;
import com.sun.media.sound.SoftTuning;
import jdk.management.resource.internal.inst.SocketOutputStreamRMHooks;

/**
 * Created by chenss on 2022/9/15.
 */
public class SpeedController {
    private int sendtmpCount = 0;
    private long tmpl = System.currentTimeMillis();
    private final RateLimiter rateLimiter = RateLimiter.create(1000);

    public boolean isTimeLimitInSecond(int maxSendInSecond, boolean sleep) {
        System.out.println(sendtmpCount);
        if (++sendtmpCount >= maxSendInSecond) {
            long l = System.currentTimeMillis() - tmpl;
            if (l < 1000) {
                try {
                    if (sleep)
                        Thread.sleep(1000 - l);
                    return true;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            sendtmpCount = 1;
            tmpl = System.currentTimeMillis();
        }
        return false;
    }

    public boolean isTimeLimitInSecond2(int maxSendInSecond, boolean sleep) {
        long l = System.currentTimeMillis() - tmpl;
//        System.out.println(sendtmpCount + "  "+ l);
        if (l >= 1000) {
            System.out.println("maxSendInSecond:" + maxSendInSecond + " sendtmpCount:" + sendtmpCount + " time:" + l);
            tmpl = System.currentTimeMillis();
            sendtmpCount = 0;
        }
        if (++sendtmpCount >= maxSendInSecond) {
            return true;
        }
        return false;
    }


    public boolean isTimeLimitInSecond() {
        sendtmpCount++;
        long l = System.currentTimeMillis() - tmpl;
        if (l >= 1000) {
            System.out.println("rate:" + rateLimiter.getRate() + " sendtmpCount:" + sendtmpCount + " time:" + l);
            tmpl = System.currentTimeMillis();
            sendtmpCount = 0;
        }
        if (!rateLimiter.tryAcquire()) {
            return true;
        }
        return false;
    }

    public void changeRate(int maxSendInSecond) {
        if (maxSendInSecond == 0) return;
        int rate = (int) rateLimiter.getRate();
        if (rate != maxSendInSecond) {
            rateLimiter.setRate(maxSendInSecond);
            System.out.println("change rate form " + rate + " to " + maxSendInSecond);
        }
    }

    public static void main(String[] args) {
        SpeedController sc = new SpeedController();
        long last = System.currentTimeMillis();
//        RateLimiter rateLimiter=RateLimiter.create(1000);
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
//            if(i%2==0)
            ThreadUtil.sleep(1);
//            rateLimiter.acquire();
            sc.changeRate(700);
//            if (sc.isTimeLimitInSecond3(1000, false)) {
            if (sc.isTimeLimitInSecond()) {
                System.out.println("failed " + i + " " + System.currentTimeMillis());
            }
//            if(i%1000==0){
//                long t2 = System.currentTimeMillis();
//                System.out.println("time:"+(t2-last));
//                last=t2;
//            }
        }
    }
}

